#include "Processo.h"

/*
 * A estrutura MemoriaSuporte será o tipo usado na estrutura da memória física.
 * Tanto para alocar na memória como pesquisar na memória usaremos essa estru-
 * tura. O parâmetro 'id' contem o id do processo e o parâmetro 'instrucao'
 * guardará a informacão importânte/não importânte do processo.
 */

typedef struct memoriasuporte ms;
struct memoriasuporte{
    int pagina;
    int indice;
    int id;
    int instrucao;
};

typedef union mem{
    TabelaProcesso tp;
    int presenteAusente;
    int protecaoLeitura;
    int protecaoEscrita;
    int protecaoExecucao;
    int modificada;
    int referenciada;
    int fifoRam;
    int desabilitaCache;
    ms ms;
}mem;


/*
 * molduraPagina: numero Numero da moldura de pagina
 * presenteAusente: 1 a pagina virtual esta na memoria principal e pode ser usada, 
 * caso contrario causara uma falta de pagina e ela tera que ser carregada do disco.
 * protecaoLeitura: se 1 leitura protegida
 * protecaoEscrita: se 1 escrita protegida
 * protecaoExecucao: se 1 execucao protegida
 * modificada: se 1 modificada
 * referenciada: se 1 referenciada
 * desabilitaCache: se 1 desabilita cache
 */
typedef struct memVir{
    int id;
    int instrucao;
    int indice;
    int pagina;
    int presenteAusente;
    int protecaoLeitura;
    int protecaoEscrita;
    int protecaoExecucao;
    int modificada;
    int referenciada;
    int fifoVirtual;
    int desabilitaCache;
    //ms mvs;
}memVir;


//A funcao abaixo busca informacoes no vetor da memoria real
int buscaInformacaoReal(int id, int instrucao);

//A funcao abaixo busca informacoes no vetor da memoria virtual
int buscaInformacaoVirtual(int id, int instrucao);

//A funcao abaixo muda o valor de Execucao de um processo
void modificaProEx(Processo processo, int instrucao);

//A funcao abaixo muda o valor de Escrita de um processo
void modificaProEs(Processo processo, int instrucao);

//A funcao abaixo muda o valor de Leitura de um processo
void modificaProLe(Processo processo, int instrucao);

//A funcao abaixo sera usada pelos programadores da CPU. A cada bit igual a 1
//a funcao faz uma alteracao.
void modificaProcesso(Processo processo, int instrucao, int proLe, int proEs, int proEx);

/*
 * Essa funcão verifica qual será a importância do processo. Ela recebe um pro-
 * cesso. Cada processo é constituído de vários parâmetros, dentre eles temos:
 * prioridade (importância), instrucões (será separada na memória física e 
 * virtual) e id ("referência" do processo). Usamos a estrutura MemoriaSuporte
 * para guardar o id do processo e a instrucão, seja ela na memória física ou
 * na memória virtual. A prioridade definirá onde as instrucões do processo
 * ficará na memória (núcleo ou usuário).
 */
void verificaImportanciaProcesso(Processo processo);


/*
 * Essa funcão coloca o tipo MemoriaSuporte dentro da parte da memória que cor-
 * responde a área de Núcleo.
 */
void insereNucleo(mem mem1, Processo processo);


/*
 * Essa funcão coloca o tipo MemoriaSuporte dentro da parte da memória que cor-
 * responde a área de Usuário.
 */
void insereUsuario(mem mem1, Processo processo);

/*
 * Essa função coloca o tipo MemoriaVirtualSuporte dentro da Memória Virtual.
 */
void insereMemoriaVirtual(Processo processo, int instrucao);



void definePaginacao(Processo processo);

/*
 * Essa função retorna a ordem da página na memória ram na posição dada
 */
int defOrdem(int pos);

/*
 * Essa função corre as instruções importantes do processo que lhe é passado e 
 * verifica se as instruções estão presentes na memória ram. Se não estiverem,
 * usando o algoritmo de troca da página menos recentemente usada ele garante
 * que estas instruções estarão na memória
 */
void pagNRU(Processo processo);

/*
 * Essa função verifica se uma dada instrução de um dado processo esta presente
 * na memória
 */
bool verificaInformacaoReal(int id, int instrucao);

/*
 * Essa função retorna a menor ordem de página no espaço de usuário
 */
int menorOrdemUsuario();

/*
 * Essa função retorna a menor ordem de página no espaço de núcleo
 */
int menorOrdemNucleo();

void fifo(Processo processo);
int verificarPrimeiroNucleo();
int verificarPrimeiroUsuario();
int verificarPrimeiroVirtual();
void secondChance(Processo processo);
void tabelaPagina(memVir mem2);